/***************************************************************************\
 * The Mattise Kernel														*
 * Copyright 2007 Matthew Iselin											*
 * Licensed under the GPL													*
 *																			*
 * timer.cc																	*
 *																			*
 * Hardware timer utilities, and the control center of the kernel: the		*
 * timer interrupt handler.													*
 *																			*
\***************************************************************************/

#include <system.h>
#include <console.h>
#include <task.h>

// sets the clock rate, in counts per second
void SetClockRate( int hz )
{
	int divisor = 1193180 / hz;       /* Calculate our divisor */
	outportb(0x43, 0x36);             /* Set our command byte 0x36 */
	outportb(0x40, divisor & 0xFF);   /* Set low byte of divisor */
	outportb(0x40, divisor >> 8);     /* Set high byte of divisor */
}

// tick timers
volatile unsigned int tick = 0;
volatile unsigned int sc = 0;

// rate for the clock in ticks per second
const int clockrate = 1000;

// timer IRQ handler
void timer_handler( struct regs* r )
{
	// increment the tick timer
	tick++;
	
	// check for second
	if( tick % clockrate == 0 )
	{
		sc++;
	}
	
	// handle multitasking - task switch
	if( mtenabled() /*&& tick % 10 == 0*/ ) { resched(); };
}

// installs the timer
void install_timer()
{
	// install the irq
	irq_install_handler( 0, timer_handler );
	
	// set the clock to tick every millisecond
	SetClockRate( clockrate );
}

// sleep/delay
void sleep( int seconds )
{
	// start time
	unsigned int now = sc;
	
	// wait...
	while( sc - now != seconds );
}
void delay( int ms )
{
	// start time
	unsigned int now = tick;
	
	// wait...
	while( tick - now != ms );
}

// clock count
unsigned int clock()
{
	return tick;
}
